<?php
/**
 * 独立语音测试HTTP服务器
 * 启动命令：php -S 127.0.0.1:8585 voice_test_server_standalone.php
 * 
 * 这是一个独立版本，不依赖 simple_server.php
 */

error_reporting(E_ALL);
ini_set('display_errors', 'on');

/**
 * 日志记录函数
 */
function logMsg(string $msg): void {
    $logDir = __DIR__ . '/logs';
    if (!is_dir($logDir)) {
        @mkdir($logDir, 0755, true);
    }
    
    $logFile = $logDir . '/' . date('Y-m-d') . '.log';
    $timestamp = date('Y-m-d H:i:s');
    $line = "[{$timestamp}] {$msg}\n";
    
    file_put_contents($logFile, $line, FILE_APPEND | LOCK_EX);
    echo $line; // 同时输出到控制台
}

/**
 * 播放语音文件（电脑外放）
 *
 * @param string $voiceType 语音类型：success=签到成功, end=结束签到, duplicate=请勿重复刷脸
 */
function playVoice(string $voiceType): void {
    $voiceDir = __DIR__ . '/voice';

    // 为每种类型准备候选文件：只使用 MP3
    $candidates = [
        'success' => [
            $voiceDir . '/checkin_success.mp3',
        ],
        'end' => [
            $voiceDir . '/checkin_end.mp3',
        ],
        'duplicate' => [
            $voiceDir . '/checkin_duplicate.mp3',
        ],
    ];

    $voiceFile = null;
    foreach (($candidates[$voiceType] ?? []) as $f) {
        if (is_file($f)) { 
            $voiceFile = $f; 
            break; 
        }
    }

    if (!$voiceFile) {
        logMsg("[VOICE] Voice file not found: {$voiceType}, using TTS");
        // 文件不存在则使用 TTS
        playVoiceByTTS($voiceType);
        return;
    }

    logMsg("[VOICE] Playing voice: {$voiceType} -> {$voiceFile}");

    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        // Windows 平台 - 使用 mciSendString 播放 MP3（最可靠的方法）
        $realPath = realpath($voiceFile);

        // 保存到临时文件执行（避免命令行长度限制）
        $tempScript = sys_get_temp_dir() . '/play_voice_' . uniqid() . '.ps1';
        file_put_contents($tempScript, str_replace('FILE_PATH', str_replace('\\', '\\\\', $realPath), <<<'POWERSHELL'
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class AudioPlayer {
    [DllImport("winmm.dll")]
    private static extern long mciSendString(string command, System.Text.StringBuilder returnValue, int returnLength, IntPtr winHandle);

    public static void Play(string file) {
        mciSendString("close MediaFile", null, 0, IntPtr.Zero);
        mciSendString("open \"" + file + "\" type mpegvideo alias MediaFile", null, 0, IntPtr.Zero);
        mciSendString("play MediaFile", null, 0, IntPtr.Zero);
    }
}
"@
[AudioPlayer]::Play("FILE_PATH")
POWERSHELL
));

        $command = 'powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "' . $tempScript . '"';
        exec('start /B "" ' . $command);

        // 延迟删除临时文件
        register_shutdown_function(function() use ($tempScript) {
            @unlink($tempScript);
        });
    } else {
        // Linux/Mac 使用 mpg123 播放（需预装）
        $command = "mpg123 -q " . escapeshellarg($voiceFile) . " > /dev/null 2>&1 &";
        exec($command);
    }
}

/**
 * 使用Windows TTS播放语音（备用方案）
 *
 * @param string $voiceType 语音类型
 */
function playVoiceByTTS(string $voiceType): void {
    $texts = [
        'success' => '签到成功',
        'end' => '结束签到',
        'duplicate' => '请勿重复刷脸'
    ];

    $text = $texts[$voiceType] ?? '签到成功';

    logMsg("[VOICE] Playing TTS: {$text}");

    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        // 使用Windows SAPI TTS
        $psCommand = 'Add-Type -AssemblyName System.Speech; ' .
                     '$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; ' .
                     '$speak.Rate = 0; ' .
                     '$speak.Volume = 100; ' .
                     '$speak.Speak(\'' . $text . '\');';

        $command = 'powershell -WindowStyle Hidden -Command "' . $psCommand . '"';

        // 异步执行（使用 exec 而不是 popen）
        exec('start /B "" ' . $command);
    }
}

/**
 * 返回JSON响应
 */
function respond_json($data, int $code = 200) {
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}

/**
 * 返回HTML页面
 */
function respond_html(string $html) {
    header('Content-Type: text/html; charset=utf-8');
    echo $html;
}

// ==================== 路由处理 ====================

logMsg("[SERVER] Request: {$_SERVER['REQUEST_METHOD']} {$_SERVER['REQUEST_URI']}");

$path = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';

// 首页路由
if ($path === '/' || $path === '/index') {
    respond_html('<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>语音测试服务器</title>
    <style>
        body {
            font-family: "Microsoft YaHei", Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: #f5f5f5;
        }
        .container {
            background: white;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            border-bottom: 3px solid #4CAF50;
            padding-bottom: 10px;
        }
        .test-buttons {
            margin: 20px 0;
        }
        .btn {
            display: inline-block;
            padding: 12px 24px;
            margin: 10px 10px 10px 0;
            background: #4CAF50;
            color: white;
            text-decoration: none;
            border-radius: 4px;
            transition: background 0.3s;
        }
        .btn:hover {
            background: #45a049;
        }
        .btn-end {
            background: #2196F3;
        }
        .btn-end:hover {
            background: #0b7dda;
        }
        .btn-duplicate {
            background: #ff9800;
        }
        .btn-duplicate:hover {
            background: #e68900;
        }
        .info {
            background: #e7f3fe;
            border-left: 4px solid #2196F3;
            padding: 15px;
            margin: 20px 0;
        }
        .api-info {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 4px;
            margin: 20px 0;
        }
        code {
            background: #f4f4f4;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: Consolas, monospace;
        }
        .status {
            margin: 20px 0;
            padding: 10px;
            background: #dff0d8;
            border: 1px solid #d6e9c6;
            border-radius: 4px;
            color: #3c763d;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎤 语音测试服务器</h1>
        
        <div class="status">
            ✅ 服务器运行正常 - ' . date('Y-m-d H:i:s') . '
        </div>
        
        <div class="info">
            <strong>📢 说明：</strong>点击下方按钮测试语音播放功能。语音将在<strong>运行此服务器的电脑</strong>上播放。
        </div>
        
        <div class="test-buttons">
            <h3>快速测试：</h3>
            <a href="/play?type=success" class="btn" target="_blank">🎵 播放：签到成功</a>
            <a href="/play?type=end" class="btn btn-end" target="_blank">🎵 播放：结束签到</a>
            <a href="/play?type=duplicate" class="btn btn-duplicate" target="_blank">🎵 播放：请勿重复刷脸</a>
        </div>
        
        <div class="api-info">
            <h3>📡 API 接口：</h3>
            <p><strong>播放语音：</strong></p>
            <code>GET /play?type={success|end|duplicate}</code>
            
            <p style="margin-top: 15px;"><strong>示例：</strong></p>
            <code>curl http://127.0.0.1:8585/play?type=success</code>
            
            <p style="margin-top: 15px;"><strong>响应：</strong></p>
            <code>{"ok": true, "type": "success", "time": "2025-10-15 15:30:00"}</code>
        </div>
        
        <div class="info">
            <strong>💡 提示：</strong>
            <ul>
                <li>优先播放语音文件（WAV/MP3）</li>
                <li>如果文件不存在，自动使用 Windows TTS</li>
                <li>语音文件位置：<code>tools/device_tcp/voice/</code></li>
                <li>日志文件位置：<code>tools/device_tcp/logs/</code></li>
            </ul>
        </div>
    </div>
</body>
</html>');
    exit;
}

// 播放路由
if ($path === '/play') {
    $type = strtolower(strval($_GET['type'] ?? 'success'));
    
    // 验证类型
    $validTypes = ['success', 'end', 'duplicate'];
    if (!in_array($type, $validTypes)) {
        respond_json([
            'ok' => false, 
            'error' => 'Invalid type. Valid types: ' . implode(', ', $validTypes)
        ], 400);
        exit;
    }
    
    try {
        playVoice($type);
        respond_json([
            'ok' => true, 
            'type' => $type, 
            'time' => date('Y-m-d H:i:s')
        ]);
    } catch (Throwable $e) {
        logMsg("[ERROR] " . $e->getMessage());
        respond_json([
            'ok' => false, 
            'error' => $e->getMessage()
        ], 500);
    }
    exit;
}

// 健康检查路由
if ($path === '/health') {
    respond_json([
        'ok' => true,
        'status' => 'running',
        'time' => date('Y-m-d H:i:s'),
        'php_version' => PHP_VERSION,
        'os' => PHP_OS
    ]);
    exit;
}

// 其他路径：404
respond_json(['ok' => false, 'error' => 'Not Found'], 404);

